#!/usr/bin/env ruby

#Philip C. Pilosi   and     Todd R. Silvia 
#   668828058                  660667901



#Random Notes
=begin
#This line of code works..took an fixnum(int) called to_string on it then appended
#it to the string that was being printed out.
#puts "\n\nThe number of command line arguments is: " + ARGV.length.to_s

Semicolons can be used to put multiple logic statements on a single line.
They are not necessary at the end of a single statement on a single line.

#Functions will return the last line of code that they execute.
#cursor = (row * SIZE_OF_ROW) + col;#This equation works for finding location in array based on row||col.

##This worked for String Tokenizing
#lol = fileArray[0].to_s;
#puts "Before: " + lol;
#test = lol.	split(" ");
#puts "After: " + test.length.to_s;

#Example of using Array like a stack.
list = [];
list.push "asdf"
list.push "qwer"
list.push "poiu"
p list;
list.pop;
p list;

//Goal:
Design Queue,Stack to be used later for BFS/DFS. //Array class handles the data structs we want
Possibly implement a pseudo BFS/DFS

//Note: (3/30/11 - 2:34pm)
Consider reading up on doing threads, that way since we have to apply the algorithm to solve 5 different
goals it can be done concurrently. (Just a thought)

=end

#Global Variables
SIZE_OF_ROW = 22;
DIRECTIONS = [-1,-22,1,22]; #Left,Up,Right,Down
nodesVisited = [];
nodesVisited.push(0);

#Function defintions!!!
#Basic function with no parameters that prints a message to the screen.
def welcomeMessage
	puts "Program 3 CS 441 Ruby Maze Solver";
	
end


#Function that returns number of command line arguments.
def cmdLineArgs
	ARGV.length
end

#Function for checking that user gave enough cmd line arguments.
def usageCheck
	if(ARGV.length < 1)
		puts "Invalid number of command line arguments"
		puts "Please enter a valid file name."
		fileName = gets.chomp		
	else
		ARGV[0]
	end
end

#Function for printing an array.
def printArray(fileArray)
	fileArray.each do |stuff|
		puts stuff 
	end

end



#Opens a file and creates an array where each element is a new line
#from the file.
def fileOpen(dataFile)
	begin
		filePtr = File.new(dataFile,'r')
		filePtr.readlines
		
	#Rescue is basically for catching the exception.
	rescue Exception => errorMessage
		puts errorMessage
		exit
	end
end

#Works in creating the base board, needs to have walls added
#fixBoard handles this. ***Consider merging blankBoard with fixBoard***(Makes sense)
def blankBoard
	board = [].fill(0,484) {"."};
	board.fill(0,22) {"#"};
	board.fill(462,483) {"#"};
end

#(works) Adds in the wall border for the 20x20 maze
def fixBoard(board)
	for i in 0..483
		if( ((i+1) % 22 ) == 1)
			board[i] = "#";
		
		else if ( ((i+1) % 22 ) == 21)
			board[i+1] = "#";
		end
		
		end
	end
	board[23] = "S";
	board
end

#Prints a correct looking board
def printBoard(board)
	for i in 0..483
		print board[i]+ " ";
		if(((i+1) % 22) == 0)
			puts
		end
	end
end

#Use this function to parse
def getCoordinates(data,foundCoordinates)
	numbersTokenized = data.split(" ");
	row = Integer(numbersTokenized[0]);
	col = Integer(numbersTokenized[1]);
	
	if(((row < 1) || (row > 20)) || ((col < 1) || (col > 20)))
		foundCoordinates[0] = row;
		foundCoordinates[1] = col;
		foundCoordinates[2] = false;
		foundCoordinates;
	else
		if((row == 1) && (col == 1))
			foundCoordinates[0] = row;
			foundCoordinates[1] = col;
			foundCoordinates[2] = false;
			foundCoordinates;
		else
			foundCoordinates[0] = row;
			foundCoordinates[1] = col;
			foundCoordinates[2] = true;
			foundCoordinates;
		end
	end
end


def insertWalls(board,coordinateList)
	puts  "Reading blocked maze positions, (end input with value \"1 1\")..."
	coords = [0,0,false];
	for i in 0..coordinateList.length-2
		valid = getCoordinates(coordinateList[i],coords);
		if(coords[2] == true)
			#Place coordinate
			cursor = (coords[0] * SIZE_OF_ROW) + coords[1];
			board[cursor] = "#";
			
		else
			#Print message that found coordinates were not valid.
			puts "Coordinates: " + coords[0].to_s + "," + coords[1].to_s + " were found to not be valid.";
		end
	end
	board;
end

#Check to see if given location is blank
def checkBlank(board,index)
	if(board[index] == ".")
		true;
	else
		false;
	end

end

#Check to see if given location is a GOAL spot.
def goalFound(board,index)
	if(board[index] == "G")
		true;
	else
		false;
	end
end


#Function to determine where the goals of the current maze will be.
def findGoals(board)
	goalList = [0,0,0,0,0];
	counter = 0;
	
	while counter < 5 do
		possibleGoal = rand(483) + 23;
		valid = checkBlank(board,possibleGoal);
	
		if(valid == true)
			goalList[counter] = possibleGoal;
			board[possibleGoal] = "G";
			counter = counter + 1;
		end		
	end
	print  "Goal list: " 
	print  goalList;
	board;
end

def applyBFS(bfsBoard)
	passString = ""
	bfsBoard.each do |spot|
		passString += spot
	end
	system("ruby","BFSSearch.rb", passString)
end

def applyDFS(dfsBoard)

	passString = ""
	dfsBoard.each do |spot|
		passString += spot
	end
	system("ruby","DFSSearch.rb", passString)		
end


#Function call (no parameters)
welcomeMessage

#Checks number of cmd line args, if incorrect gets file name from user.
dataFile = usageCheck;

#Opens the file and creates and array that represents the file.
fileArray = fileOpen(dataFile);

#Create a blank board.
gameBoard = blankBoard;

gameBoard = fixBoard(gameBoard);

#Function to insert one wall, get this working then expand to insert all of the walls.
gameBoard = insertWalls(gameBoard,fileArray);

#Find goals(not done)
gameBoard = findGoals(gameBoard);

puts;

printBoard(gameBoard);



####################################################################
#At this point the board is setup and ready for an algorithm to be #
#applied to it for finding a solution.                             #
####################################################################

##Deep copy of the game board.
dfsBoard = Array.new(gameBoard);
bfsBoard = Array.new(gameBoard);

#applyBFS(bfsBoard)
#applyDFS(dfsBoard)

puts "Program done, exiting";